package com.zh.freechat.web;

import com.zh.freechat.assemble.ChatUserWrapper;
import com.zh.freechat.common.req.param.UserParam;
import com.zh.freechat.common.req.ChatUserForm;
import com.zh.freechat.common.req.PasswordUpdateForm;
import com.zh.freechat.common.req.UserUpdateForm;
import com.zh.freechat.common.resp.ChatUserVO;
import com.zh.freechat.domain.user.ChatUserDTO;
import com.zh.freechat.domain.user.entity.ChatUser;
import com.zh.freechat.domain.user.service.ChatUserService;
import com.zh.freechat.domain.validcode.ValidateCodeService;
import com.zh.webcommon.common.viewdata.ApiResult;
import com.zh.webcommon.common.auth.annotation.NonePermission;
import com.zh.webcommon.common.log.annotation.OperateLog;
import jakarta.validation.Valid;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.util.HtmlUtils;

import java.util.List;
import java.util.stream.Collectors;

/**
 * 用户相关API
 * @author ZH
 * @date 15:36 2021/7/31
 */
@AllArgsConstructor
@Slf4j
@RestController
@RequestMapping("/user")
public class UserController {
    private ChatUserService userService;
    private ValidateCodeService verifyCodeService;

    /**
     * 用户注册
     */
    @NonePermission
    @OperateLog("用户注册")
    @PostMapping("/register")
    public ApiResult<Void> registerUser(@RequestBody @Valid ChatUserForm form, @RequestHeader("X-uuid") String uuid) {
        //TODO 开发临时用
        boolean notCheckCode = "000000".equals(form.getCode());

        String identity = StringUtils.hasText(form.getEmail()) ? form.getEmail() : form.getPhone();
        if (!StringUtils.hasText(identity)) {
            throw new IllegalArgumentException("手机号或邮箱不能为空");
        }

        if (!notCheckCode) {
            verifyCodeService.validateSmsCode(form.getCode(), uuid);
        }

        var uid = userService.addUser(form);
        log.info("【注册账号】[userId={}, identity={}] ", uid, identity);

        userService.activeUser(uid);
        log.info("【账号已激活】[userId={}, identity={}] ", uid, identity);

        return ApiResult.success();
    }

    /**
     * 检查username或phone是否被占用
     */
    @NonePermission
    @GetMapping("/isOccupy")
    public ApiResult<Boolean> isOccupyUsernameOrPhone(@RequestParam String str) {
        Boolean occupy = userService.isOccupy(str.trim());
        return ApiResult.success(occupy);
    }

    /**
     * 删除(逻辑)用户
     */
    @OperateLog("删除(逻辑)用户")
    @DeleteMapping("/{id}")
    public ApiResult<Void> removeUser(@PathVariable String id) {
        userService.removeUser(id);

        log.info("已删除(逻辑)User：" + id);
        return ApiResult.success();
    }

    /**
     * 冻结用户
     */
    @OperateLog("冻结用户")
    @PutMapping("/freeze/{id}")
    public ApiResult<Void> freezeUser(@PathVariable String id) {
        userService.freezeUser(id);

        log.info("已冻结User：" + id);
        return ApiResult.success();
    }

    /**
     * 激活用户
     */
    @NonePermission
    @OperateLog("激活用户")
    @PutMapping("/active/{id}")
    public ApiResult<Void> activeUser(@PathVariable String id) {
        userService.activeUser(id);

        log.info("已激活User：" + id);
        return ApiResult.success();
    }

    /**
     * 更改密码
     */
    @OperateLog("更改密码")
    @PutMapping("/password/{id}")
    public ApiResult<Void> editPassword(@PathVariable String id, PasswordUpdateForm form) {
        userService.editPassword(id, form.getPassword(), form.getOldpassword());

        log.info("更改密码成功 User：" + id);
        return ApiResult.success();
    }

    /**
     * 更改头像
     */
    @PutMapping("/avatar/{id}")
    public ApiResult<Void> editAvatar(@PathVariable String id, UserUpdateForm form) {
        userService.editAvatar(id, form.getAvatarUrl());

        log.info("更改头像成功 User：" + id);
        return ApiResult.success();
    }

    /**
     * 更改手机号
     */
    @OperateLog("更改手机号")
    @PutMapping("/phone/{id}")
    public ApiResult<Void> editPhone(@PathVariable String id, UserUpdateForm form) {
        userService.editPhone(id, form.getPhone());

        log.info("更改手机号成功 User：" + id);
        return ApiResult.success();
    }

    /**
     * 更改个人信息
     */
    @OperateLog("更改个人信息")
    @PutMapping("/edit/{id}")
    public ApiResult<Void> editProfile(@PathVariable String id, UserUpdateForm form) {
        userService.editProfile(id, HtmlUtils.htmlEscape(form.getProfile()));

        log.info("更改个人简介成功 User：{}",id);
        return ApiResult.success();
    }

    /**
     * 根据ID查找user
     */
    @GetMapping("/{id}")
    public ApiResult<ChatUserDTO> findById(@PathVariable String id) {
        ChatUser chatUser = userService.findById(id);

        return ApiResult.success(ChatUserWrapper.wrapperDTO(chatUser));
    }

    /**
     * 根据username查找user
     */
    @GetMapping("/username/{username}")
    public ApiResult<ChatUserDTO> findUserByUsername(@PathVariable String username) {
        ChatUser chatUser = userService.findByUsername(username);

        return ApiResult.success(ChatUserWrapper.wrapperDTO(chatUser));
    }

    /**
     * 根据 phone查找user
     */
    @GetMapping("/phone/{phone}")
    public ApiResult<ChatUserDTO> findUserByPhone(@PathVariable String phone) {
        ChatUser chatUser = userService.findByPhone(phone);

        return ApiResult.success(ChatUserWrapper.wrapperDTO(chatUser));
    }

    /**
     * 搜索用户
     * 根据手机号，邮箱，或username，或昵称
     */
    @GetMapping("/search")
    public ApiResult<List<ChatUserVO>> searchChatUser(@RequestParam String kw, @RequestParam(defaultValue = "") String flag) {
        List<ChatUserVO> chatUsers = userService.searchChatUserByKeyword(kw.trim(), flag.equals("direct"));
        log.info("搜索用户成功 Users = {}", chatUsers.stream().map(ChatUserVO::getUsername).collect(Collectors.toSet()));
        return ApiResult.success(chatUsers);
    }

    /**
     * 分页查询 用户(全部状态)
     *
     * @param
     * @return
     */
    @GetMapping("/page")
    public ApiResult<Page<ChatUser>> findPage(UserParam param) {
        Page<ChatUser> page = userService.findPage(param);
        return ApiResult.success(page);
    }

}
